package com.justgame.project.base.interceptor;

import com.justgame.project.base.annotation.VerificationCode;
import com.justgame.project.cloud.common.constant.Const;
import com.justgame.project.cloud.common.util.AssertKit;
import com.justgame.project.cloud.common.util.Encryption;
import com.justgame.project.cloud.common.util.ObjUtil;
import com.justgame.project.cloud.common.util.RedisUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Optional;

/**
 * VerificationCode（验证码注解） Controller拦截器
 */
@Component
@AllArgsConstructor
public class VerificationCodeInterceptor implements HandlerInterceptor {
    @Resource
    private final RedisUtils redisUtils;

    private boolean isValidate(Object handler) {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        VerificationCode annotation = method.getAnnotation(VerificationCode.class);
        if (annotation != null) {
            return ((VerificationCode) annotation).value();
        } else {
            return false;
        }
    }

    private boolean ValidateRequest(HttpServletRequest request) {
        String headerCode = Optional.ofNullable(request.getHeader(Const.KEY_VERIFICATION_CODE_2WEB))
                .orElseThrow(()->new IllegalArgumentException("验证码已失效"))
                .toLowerCase();
        AssertKit.hasLength(headerCode, "验证码已失效");
        StringBuffer sb = Encryption.PasswordMD5(headerCode);
        HttpSession session = request.getSession();
        String sessionCode = String.valueOf(Optional.ofNullable(
                session.getAttribute(Const.KEY_VERIFICATION_CODE_2WEB))
                .orElse(redisUtils.get(request.getSession().getId()))
        );
        AssertKit.isEquals(sessionCode, sb.toString(), "验证码不正确");
        redisUtils.delete(session.getId());
        session.removeAttribute(Const.KEY_VERIFICATION_CODE_2WEB);
        return true;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            if (isValidate(handler)) {
                return ValidateRequest(request);
            }
        }
        return true;

    }
}
